﻿using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using HandyControl.Controls;
using HandyControl.Data;
using Microsoft.Extensions.Logging;
using ShanNiang.Hosting;
using ShanNiang.Hosting.Enumerate;
using ShanNiang.Mvvm.UiServices;
using ShanNiang.Service;
using ShanNiang.Service.Constants;
using ShanNiang.Service.Enumerate;
using ShanNiang.Service.Implementations;
using ShanNiang.Service.Interfaces;
using ShanNiang.Service.PackingModels.Requests;
using ShanNiang.Service.Scaner;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ShanNiang.Mvvm.ViewModels
{
    public partial class PackBoxHistoryViewModel : ScannableViewModel
    {
        #region 服务入驻
        private readonly ISoundService _soundService;
        private readonly UserContext _userContext;
        private readonly IXkmService _xkmService;
        private readonly ItemViewModel _emptyItem;
        private readonly WorkerViewModel _emptyWorker;
        #endregion

        public PackBoxHistoryViewModel(
            IUiService uiService,
            ISoundService soundService,
            UserContext userContext,
            IXkmService xkmService,
            PackingConfig packingConfig, IScanerService scanerService, IMapper mapper, ILogger<PackBoxHistoryViewModel> logger) : base(packingConfig, scanerService, uiService, mapper, logger)
        {
            _soundService = soundService;
            _userContext = userContext;
            _xkmService = xkmService;
            Boxes = new ObservableCollection<BoxDetailViewModel>();
            Items = new ObservableCollection<ItemViewModel>();
            Records = new ObservableCollection<PackingRecordViewModel>();
            Workers = new ObservableCollection<WorkerViewModel>();
            _emptyItem = new ItemViewModel { Name = "全部商品", ImageUrl = "/Images/emptybottle.png" };
            _emptyWorker = new WorkerViewModel { RealName = "全部员工", HeadImg= "/Images/packing.png" };
            //for (var i = 0; i < 10; i++)
            //{
            //    Boxes.Add(new BoxDetailViewModel { BottleCount = 9, BoxCode = Convert.ToBase64String(BitConverter.GetBytes(new Random().NextInt64())) });
            //}
            
        }
        #region 字段和可观察属性
        /// <summary>
        /// 商品当前页码
        /// </summary>
        [ObservableProperty]
        private int _boxPageIndex;
        /// <summary>
        /// 箱码总页面
        /// </summary>
        [ObservableProperty]
        private int _boxTotalPages;
        ///// <summary>
        ///// 当前日期
        ///// </summary>
        //[ObservableProperty]
        //private DateTime? _currentDate;
        /// <summary>
        /// 当前商品
        /// </summary>
        [ObservableProperty]
        private ItemViewModel? _currentItem;
        /// <summary>
        /// 当前记录
        /// </summary>
        [ObservableProperty]
        private PackingRecordViewModel? _currentRecord;
        /// <summary>
        /// 当前操作人
        /// </summary>
        [ObservableProperty]
        private WorkerViewModel? _currentWorker;
        /// <summary>
        /// 商品当前页码
        /// </summary>
        [ObservableProperty]
        private int _itemPageIndex;
        /// <summary>
        /// 商品总页数
        /// </summary>
        [ObservableProperty]
        private int _itemTotalPages;
        /// <summary>
        /// 装箱记录页码
        /// </summary>
        [ObservableProperty]
        private int _recordPageIndex;
        /// <summary>
        /// 装箱记录总页面
        /// </summary>
        [ObservableProperty]
        private int _recordTotalPages;
        ///// <summary>
        ///// 展示选择框，
        ///// </summary>
        //[ObservableProperty]
        //private bool _showItems;

        /// <summary>
        /// 查找到的箱码
        /// </summary>
        public ObservableCollection<BoxDetailViewModel> Boxes { get; set; }
        /// <summary>
        /// 当前企业
        /// </summary>
        private Guid? CurrentEnterpriseId
        {
            get
            {
                if (_userContext.UserResponse != null)
                {
                    return _userContext.UserResponse.EnterpriseId;
                }
                return null;
            }
        }
        /// <summary>
        /// 可选商品
        /// </summary>
        public ObservableCollection<ItemViewModel> Items { get; set; }
        /// <summary>
        /// 页面大小
        /// </summary>
        public int PageSize => CommonData.DEFAULT_PAGE_SIZE;
        /// <summary>
        /// 可选装箱记录
        /// </summary>
        public ObservableCollection<PackingRecordViewModel> Records { get; set; }
        /// <summary>
        /// 装箱人
        /// </summary>
        public ObservableCollection<WorkerViewModel> Workers { get; set; }
        #endregion

        #region 可绑定 Command
        [RelayCommand]
        private void ClearConditions()
        {
            //CurrentRecord = null;
            CurrentItem = _emptyItem;
            CurrentWorker = _emptyWorker;
        }
        [RelayCommand]
        private async Task LoadBoxesAsync(FunctionEventArgs<int> parameter)
        {
            if (CurrentRecord != null && CurrentItem !=null)
            {
                GetPackingBoxesPageRequest request = new GetPackingBoxesPageRequest(CurrentRecord.Id);
                if (CurrentItem != null && CurrentItem.Id != Guid.Empty)
                {
                    request.ItemId = CurrentItem.Id;
                }
                if (CurrentWorker != null && CurrentWorker.Id != Guid.Empty) 
                {
                    request.UserId = CurrentWorker.Id;
                }
                if (parameter != null)
                {
                    ItemPageIndex = parameter.Info;
                }
                request.PageIndex = ItemPageIndex;
                request.PageSize = CommonData.DEFAULT_PAGE_SIZE;
                var response = await _xkmService.GetPackingBoxesPageAsync(request);
                if (response != null)
                {
                    var boxList = Mapper.Map<List<BoxDetailViewModel>>(response.List);
                    Boxes.Clear();
                    foreach (var box in boxList)
                    {
                        Boxes.Add(box);
                    }
                    //ShowItems = true;
                    BoxTotalPages = (response.TotalCount - 1) / request.PageSize + 1;
                }
            }
        }
        /// <summary>
        /// 刷新商品
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task LoadItemsAsync()
        {
            if (CurrentRecord != null)
            {
                var request = new GetPackingItemsRequest();
                //if (parameter != null)
                //{
                //    ItemPageIndex = parameter.Info;
                //}
                request.PackingRecordId = CurrentRecord.Id;
                //request.PageIndex = ItemPageIndex;
                //request.PageSize = CommonData.DEFAULT_PAGE_SIZE;
                var response = await _xkmService.GetPackingItemsAsync(request);
                if (response != null)
                {
                    var itemList = Mapper.Map<List<ItemViewModel>>(response);
                    Items.Clear();
                    foreach (var item in itemList)
                    {
                        Items.Add(item);
                    }
                    CurrentItem = _emptyItem;
                    //ShowItems = true;
                    //ItemTotalPages = (response.TotalCount - 1) / request.PageSize + 1;
                }
            }
        }
        /// <summary>
        /// 刷新商品
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task LoadRecordsAsync(FunctionEventArgs<int> parameter)
        {
            GetPackingRecordsPageRequest request = new GetPackingRecordsPageRequest();
            if (parameter != null)
            {
                ItemPageIndex = parameter.Info;
            }
            request.PageIndex = ItemPageIndex;
            request.PageSize = CommonData.DEFAULT_PAGE_SIZE;
            var response = await _xkmService.GetPackingRecordsPageAsync(request);
            if (response != null)
            {
                var recordList = Mapper.Map<List<PackingRecordViewModel>>(response.List);
                Records.Clear();
                foreach (var record in recordList)
                {
                    Records.Add(record);
                }
                CurrentRecord = Records.FirstOrDefault();
                RecordTotalPages = (response.TotalCount - 1) / request.PageSize + 1;
            }
        }
        /// <summary>
        /// 刷新装箱人
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        private async Task LoadWorkersAsync()
        {
            if (CurrentRecord != null)
            {
                var request = new GetPackingUsersRequest();
                //if (parameter != null)
                //{
                //    ItemPageIndex = parameter.Info;
                //}
                request.PackingRecordId = CurrentRecord.Id;
                //request.PageIndex = ItemPageIndex;
                //request.PageSize = CommonData.DEFAULT_PAGE_SIZE;
                var response = await _xkmService.GetPackingUsersRequestAsync(request);
                if (response != null)
                {
                    var workers = Mapper.Map<List<WorkerViewModel>>(response);
                    Workers.Clear();
                    foreach (var worker in workers)
                    {
                        Workers.Add(worker);
                    }
                    CurrentWorker = _emptyWorker;
                    //ShowItems = true;
                    //ItemTotalPages = (response.TotalCount - 1) / request.PageSize + 1;
                }
            }
        }
        [RelayCommand]
        public  void ToBoxDetail(object? boxDetail) 
        {
            if (boxDetail != null)
            {
                var boxDetailViewModel = (BoxDetailViewModel)boxDetail;
                //给 装箱 viewmodel 发消息，查询箱码
                WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<string?>(this, CommonData.ToPackingBox, null, boxDetailViewModel.BoxCode));
                //bottleViewModel.BottleCode = null;
                //BoxCode.NotifyPackedCountToChange();
            }
        }
        #endregion

        #region 重写和事件处理
        /// <summary>
        /// 页面加载
        /// </summary>
        /// <returns></returns>
        protected override async Task LoadedAsync()
        {
            await base.LoadedAsync();
            //if (CurrentItem == null)
            //{
            //    if (!string.IsNullOrEmpty(PackingConfig.DefaultBarcode))
            //    {
            //        await ScanBarcodeAsync(PackingConfig.DefaultBarcode);
            //    }
            //}
            //if (CurrentRecord == null)
            //{
            //    CurrentRecord = _emptyRecord;
            //}
            if (Records.Count == 0)
            {
                await LoadRecordsAsync(new FunctionEventArgs<int>(1));
            }
            //if (Items.Count == 0)
            //{
            //    await LoadItemsAsync();
            //}
            //if (Workers.Count == 0)
            //{
            //    await LoadWorkersAsync();
            //}
            //if (BoxTotalPages == 0)
            //{
            //    await LoadBoxesAsync(new FunctionEventArgs<int>(1));
            //}
        }
        protected override async void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.PropertyName == nameof(CurrentRecord))
            {
                await LoadItemsAsync();
                await LoadWorkersAsync();
                await LoadBoxesAsync(new FunctionEventArgs<int>(1));
            }
            if (e.PropertyName == nameof(CurrentItem)) 
            {
                await LoadBoxesAsync(new FunctionEventArgs<int>(1));
            }
            if (e.PropertyName == nameof(CurrentWorker))
            {
                await LoadBoxesAsync(new FunctionEventArgs<int>(1));
            }
        }
        protected override async Task CodeScanedAsync(object? sender, CodeEventArgs e)
        {
            if (e.CodeType == CodeType.Barcode)
            {
                await ScanBarcodeAsync(e.Code);
            }
            else
            {
                _soundService.PlayWanning(CodeType.Unknown);
            }
        }
        #endregion

        #region 其他方法
        private async Task ScanBarcodeAsync(string code)
        {
            var request = new GetItemRequest(code, CurrentEnterpriseId);
            try
            {
                var item = await _xkmService.GetItemAsync(request);
                if (item != null)
                {
                    CurrentItem = Mapper.Map<ItemViewModel>(item);
                    //await CheckAutoPackage();
                    _soundService.PlayInfo(CodeType.Barcode);
                }
            }
            catch (ApiException ex)
            {
                if (ex.ErrorCode == GlobalErrorCode.NotFound)
                {
                    UiService.GrowlWarning("本商品不存在", CodeType.Barcode);
                }
                else
                {
                    UiService.GrowlWarning(ex.Message, CodeType.Barcode, ex);
                }
            }
            catch (Exception ex)
            {
                UiService.GrowlError(ex.Message, CodeType.Barcode, ex);
            }
        }
        #endregion
    }
}
